﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml;
using umbraco.BusinessLogic;

namespace uREST.Core.PackageActions
{
    /// <summary>
    /// This Package action will Add a Config Section to the uREST.config file
    /// </summary>
    public class AdduRESTConfigSection : AbstractPackageAction
    {
        //Set the web.config full path
        const string FULL_PATH = "/config/uREST.config";

        /// <summary>
        /// This Alias must be unique and is used as an identifier that must match 
        /// the alias in the package action XML
        /// </summary>
        /// <returns>The Alias in string format</returns>
        public override string Alias()
        {
            return "uREST_AdduRESTConfigSection";
        }

        /// <summary>
        /// Append the xmlData node to the uREST.config file
        /// </summary>
        /// <param name="packageName">Name of the package that we install</param>
        /// <param name="xmlData">The data that must be appended to the uREST.config file</param>
        /// <returns>True when succeeded</returns>
        public override bool Execute(string packageName, System.Xml.XmlNode xmlData)
        {
            if (!xmlData.HasChildNodes)
                return false;

            var configPath = HttpContext.Current.Server.MapPath(FULL_PATH);

            var doc = new XmlDocument();

            if (!File.Exists(configPath))
            {
                doc.LoadXml("<uREST />");

                var xmlDec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                doc.InsertBefore(xmlDec, doc.DocumentElement);
            }
            else
            {
                doc.Load(configPath);
            }

            var modified = false;

            foreach (XmlNode configSection in xmlData.ChildNodes)
            {
                var configSectionName = configSection.LocalName;

                var configSectionNode = doc.DocumentElement.SelectSingleNode(configSectionName);
                if (configSectionNode == null)
                {
                    var importedNode = doc.ImportNode(configSection, true);
                    doc.DocumentElement.AppendChild(importedNode);
                    modified = true;
                }                
            }

            if (modified)
            {
                try
                {
                    //Save the Rewrite config file with the new rewerite rule
                    doc.Save(configPath);

                    return true;
                }
                catch (Exception e)
                {
                    //Log error message
                    string message = "Error at execute AdduRESTConfigSection package action: " + e.Message;
                    Log.Add(LogTypes.Error, GetUser(), -1, message);
                }
            }

            return false;
        }

        /// <summary>
        /// Removes the xmlData node from the web.config file
        /// </summary>
        /// <param name="packageName">Name of the package that we install</param>
        /// <param name="xmlData">The data that must be appended to the uREST.config file</param>
        /// <returns>True when succeeded</returns>
        public override bool Undo(string packageName, System.Xml.XmlNode xmlData)
        {
            if (!xmlData.HasChildNodes)
                return false;

            var configPath = HttpContext.Current.Server.MapPath(FULL_PATH);

            if (!File.Exists(configPath))
                return false;

            var doc = new XmlDocument();
            doc.Load(configPath);

            var modified = false;

            foreach (XmlNode configSection in xmlData.ChildNodes)
            {
                var configSectionName = configSection.LocalName;

                var configSectionNode = doc.DocumentElement.SelectSingleNode(configSectionName);
                if (configSectionNode != null)
                {
                    doc.DocumentElement.RemoveChild(configSectionNode);
                    modified = true;
                }
            }

            if (modified)
            {
                try
                {
                    if(doc.DocumentElement.HasChildNodes)
                        doc.Save(configPath);
                    else
                        File.Delete(configPath);

                    return true;
                }
                catch (Exception e)
                {
                    //Log error message
                    string message = "Error at undo AdduRESTConfigSection package action: " + e.Message;
                    Log.Add(LogTypes.Error, GetUser(), -1, message);
                }
            }

            return false;
        }
    }
}
